docker底层原理及常见问题

docker面试问题

docker网络类型

image-20251201093552972

桥接模式:

image-20251201093613963

host模式:

image-20251201093638399

Container模式:

image-20251201093703190

跨主机的网络类型:

image-20251201093825526
image-20251201111003642
创建自定义网络
docker network   create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
-d, --driver string       指定网络类型,默认是桥接bridge
     --subnet strings       指定自定义的网络的网段CIDR 172.100.0.0/16
     --ip-range strings     指定自定义网络中ip范围CIDR 172.100.1.0/24  
     --gateway strings     指定网关
创建172.100.1.0/24 桥接的
docker network create oldboy_net  --driver bridge \
--subnet 172.100.0.0/16 \
--ip-range 172.100.1.0/24 \
--gateway 172.100.0.1

ip a | grep 172.100.0.1
docker run -d  --network oldboy_net  --name diy_net nginx:1.24
docker exec   -it   diy_net   curl  -I   baidu.com
host模式网络
docker run -d   --network   host   nginx:1.24-alpine
docker run -d   --network   host   nginx:1.24-alpine
docker run -d   --network   host   nginx:1.24-alpine

小结:

单机网络类:桥接,host,container模式,none. 跨主机:overylay,fannel

docker底层原理,底层如何实现?

容器是 隔离 的环境中运行的一个 进程 ,如果进程结束,容器就会停止. 细致:容器的隔离环境,拥有自己的ip地址,系统文件,主机名,进程管理,相当于一个 mini的系统 . 容器技术是基于 Linux内核 技术实现的. namespace 命名空间,资源隔离. cgroup 资源控制/限制. overlayfs 文件系统. chroot 切换根目录.

image-20251201111545308

namespace

创建隔离的环境

查看 /proc/pid/ns/

image-20251201111712919
namespace分类:
image-20251201111739365
容器中namespace和宿主机namespace:
image-20251201111800874

cgroups

cd /sys/fs/cgroup/cpu
mkdir oldboy-cgroup
cd oldboy-cgroup
#压力测试
stress  -c 4  -v -t 20m  
#进行限制
echo 10000 >cpu.cfs_quota_us
#添加pid到tasks中 关联任务

内核参考资料

Understanding and Securing Linux Namespaces – Linux.com

Demystifying Containers – Part I: Kernel Space | by Sascha Grunert | Medium

面试题合集

说明: 面试题汇总与总结

1. 如何提取日志中关键错误

1) 
关键词过滤: error/failed/failure/exception/timeout/permission denied/
2)
docker logs + 过滤
3) docker logs  -f 或--tail 或--since 或--until    -n最后xxx行日志
docker logs -f   -n 500
docker logs -f   --since 50m

2. docker-compose,nginx使用docker启动,涉及到七八个域名,使用docker-compoes/docker run进行管理,设计一下挂载数据的逻辑,把关键的文件目录挂载+出来;规划一下;

1. 手动运行与配置
2. dockerfile
3. docker run
4. docker-compose管理   services:   networks:


1) docker run 使用了什么选项
a.子配置文件
b.代码目录
docker run  -d --name   ngx_mutil_site -p 80:80 -v  `pwd`/conf.d/:/etc/nginx/conf.d/ \
                                       -v  `pwd`/code/:/app/code/             \
                                      nginx:1.24
                                       
#挂载配置文件(conf.d)容器中
#所有项目的代码
2) docker-compose
version: '3.3'
serivces:
  ngx_mutil_site:
    image: nginx:1.24
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./conf.d/:/etc/nginx/conf.d/
      - ./code/:/app/code/  
     

3. dockerfile如何实现日志的标准输出?docker怎么将服务日志暴露出来?

docker logs本质  容器中日志文件不要存放在文件中. 输入到日志文件的内容,输出屏幕. docker logs捕获.

方案01: 软连接
1) 日志文件软连接到/dev/stdout 或 /dev/stderr
/dev/stdout --> /proc/self/fd/1
/dev/stderr --> /proc/self/fd/2

/proc/self/fd/1 /proc/self/fd/2 指向--> /dev/pts/0
方案02: 配置文件中指定
2) 服务指定日志的时候直接指定到stdout或stderr
error_log /dev/stderr;
access_log /dev/stdout;

2) docker logs查看

4. docker如何实现日志切割/轮询?

0. 一般的服务没有容器的时候,通过logrotate实现日志切割/轮询

1.存放在容器信息LogPath指定的位置. json格式.


2.daemon.json文件 docker服务配置

{
 "registry-mirrors": ["https://bjjtv7cs.mirror.aliyuncs.com"],
 "insecure-registries": ["reg.oldboylinux.cn:5000","harbor.oldboylinux.cn"],
 "log-driver": "local",
 "log-opts": {
   "max-size": "1g",
   "max-file": "15"
  }
}
   "max-size": "1g", 日志最大大小
   "max-file": "15" 日志数量

5. 你在使用k8s使用过dockerfile的多阶段构建吗?好处是什么?

通过FROM 指定镜像的时候加上AS tmp 创建临时镜像 其他FROM中通过copy  --from=tmp从临时镜像复制内容. 好处:  环境隔离 编译环境 运行环境 控制镜像大小 都放在一起镜像很大 更加安全 精简镜像大小. 应用场景: 1. 编译 tengine 2. java/maven打包编译  前端 打包 编译

6. dockerfile里面在容器作为守护进程的指令是什么?

守护进程,阻塞.

CMD或ENTRYPOINT.
举例: nginx -g 'daemon off;'
    mysqld
    php-fpm
    脚本/entry.sh java -jar
    catalina.sh run
    tail -f xxx.log

7. 你说一下写一个Dockerfile的全部流程?说下你熟悉的dockerfile的指令,其中CMD和ENTRYPOINT的区别是啥?ARG和ENV区别?COPY和ADD的区别呢?

1) 流程手动测试  docker run 手动部署,docker cp,准备配置.
记录流程与命令,操作.
 
2) 根据流程书写dockerfile
FROM
LABEL
ENV
ADD/COPY
RUN
RUN
RUN
EXPOSE  
VOLUME
WORKDIR
CMD
HEALTHCHECK 容器健康检查.指令
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
指令的返回值是 0: success - the container is healthy and ready for use
指令的返回值是 1: unhealthy - the container is not working correctly

3) 测试,精简
4) 保存,上传到镜像仓库,dk保留.
5) 清理本地镜像
1.tar   ADD
2.多阶段构建 COPY --from
3. ADD指定网络链接(wget)
ENV 创建环境变量,dockerfile中使用,脚本,容器使用. 全局变量.
ARG docker build 时候通过--build-arg指定. dockerfile中生效.

8. dockerfile有自己写吗? dockerfile 内容

同上

9. dockerfile 中下载资源的方式

外部资源-->镜像

1) ADD   nginx.org/nginx.tar.gz   /tmp/
2) RUN   wget/curl

10. dockerfile的add和copy的区别

11. 你是否用过dockerfile的cmd查看容器的pid

docker inspect 
docker inspect   tomcat_zrlog | jq .[].State.Pid

docker top 容器名字
docker top 01ngx_ngx_1   aux /-ef/-efL

12. docker网络模式

bridge桥接
host  
container
none

flannel
celico

13. docker原理

ns(namespace)  隔离
cgroup         限制
overlayfs     文件系统
chroot         根

14. docker的镜像分层?

img
dockerfile 
基础系统镜像一般是只读的.
通过dockerfile中的指令给镜像增加新的层次(修改)
每个指令相当于给镜像增加了1层.(RUN,ADD,COPY)
最终生成我们想要的自定义镜像.
img

15. k8s和dockers的区别?

16. docker如何保持文件层级?

镜像分层
overlayfs
chroot

17. docker配置文件deamon.json的配置文件参数有哪些?

{
 "registry-mirrors": ["https://bjjtv7cs.mirror.aliyuncs.com"],
 "insecure-registries": ["reg.oldboylinux.cn:5000","harbor.oldboylinux.cn"],
 "log-driver": "local",
 "log-opts": {
   "max-size": "1g",
   "max-file": "15"
  }
}
{
 "registry-mirrors": ["https://x86ltfij.mirror.aliyuncs.com"],
 "insecure-registries": ["reg.oldboylinux.cn:5000","harbor.oldboylinux.cn"],
 "features": {
     "buildkit": true
  }
}



registry-mirrors 指定镜像仓库,用于加速的地址.
insecure-registries 指定未加密的私有镜像仓库(没有使用https)
log-opts 指定日志的选项.
....

18. 容器无法启动如何排查?

  • 容器无法启动
  • logs
  • docker run -itd xxx /bin/bash,然后进入容器 手动启动服务(CMD) 检查语法
  • 可以启动exec 连接查看
  • 多容器,ping,telnet,tcpdump

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部